package com.gzist.zzchatroomserver.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gzist.zzchatroomserver.entity.dto.ResetPasswordDTO;
import com.gzist.zzchatroomserver.entity.dto.UserDTO;
import com.gzist.zzchatroomserver.entity.dto.UserSaveDTO;
import com.gzist.zzchatroomserver.entity.po.User;
import com.gzist.zzchatroomserver.interceptors.exceptions.LoginFailedException;
import com.gzist.zzchatroomserver.mapper.UserMapper;
import com.gzist.zzchatroomserver.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Optional;

/**
 *  服务实现类
 *
 * @author hzj
 * @since 2025-01-07
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    @Override
    public void login(UserDTO userDTO) {
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(User::getUsername, userDTO.getUsername());
        User user = this.getOne(wrapper);
        if (user == null) {
            throw new LoginFailedException("账号错误！");
        }
        if (!BCrypt.checkpw(userDTO.getPassword(), user.getPassword())) {
            throw new LoginFailedException("密码错误！");
        }
        if (!userDTO.getUsername().equals("admin")) {
            throw new LoginFailedException("非管理员身份！");
        }
        StpUtil.login(user.getId());
        StpUtil.getSession().set("user", user);
    }

    @Override
    public void updatePassword(HashMap<String, String> passwordMap) {
        // 获取输入的旧密码、新密码和确认密码
        String oldPassword = Optional.ofNullable(passwordMap.get("oldPassword")).orElse("null");
        String newPassword = Optional.ofNullable(passwordMap.get("newPassword")).orElse("null");
        String confirmPassword = Optional.ofNullable(passwordMap.get("confirmPassword")).orElse("null");

        verifyOldPassword(oldPassword);
        // 确保新密码和确认密码相同
        if (!newPassword.equals(confirmPassword)) {
            throw new RuntimeException("新密码和确认密码不匹配，请重新输入！");
        }
        // 更改密码
        User updateUser = new User();
        updateUser.setId(StpUtil.getLoginIdAsString());
        updateUser.setPassword(BCrypt.hashpw(newPassword));
        this.updateById(updateUser);
    }

    @Override
    public boolean resetPassword(ResetPasswordDTO resetPasswordDTO) {
        String hashpw = BCrypt.hashpw(resetPasswordDTO.getPassword());
        User user = new User();
        user.setId(resetPasswordDTO.getId());
        user.setPassword(hashpw);
        return userMapper.updateById(user) == 1;
    }

    @Override
    public void saveOrUpdateUser(UserSaveDTO userSaveDTO) {
        if (StrUtil.isBlank(userSaveDTO.getId())) {
            String hashpw = BCrypt.hashpw(userSaveDTO.getPassword());
            userSaveDTO.setPassword(hashpw);
        }
        User user = new User();
        BeanUtil.copyProperties(userSaveDTO, user);
        saveOrUpdate(user);
    }

    /**
     * 验证旧密码是否正确
     *
     * @param inputPassword 用户输入的旧密码
     */
    private void verifyOldPassword(String inputPassword) {
        // 从数据库中查询出当前用户的旧密码
        User user = this.getById(StpUtil.getLoginIdAsString());
        String queryPassword = user.getPassword();
        if (!BCrypt.checkpw(inputPassword, queryPassword)) {
            throw new RuntimeException("旧密码错误！");
        }
    }
}
